import SingleUpload from './upload';
import './style.css';

/** 文件分片大小 */
const SIZE = 2 * 1024 * 1024;

/** 请求限流 */
const CONCURRENCY = 5;

/** 分片上传失败重试次数 */
const RETRIES = 3;

// 获取元素dom
const file = document.querySelector('#file');
const hashProgress = document.querySelector('#hashProgress');
const uploadBtn = document.querySelector('#uploadBtn');
const cost = document.querySelector('#cost');
const fileURL = document.querySelector('#fileURL');
const progressBar = document.querySelector('#progress');
const speedTestButton = document.querySelector('#speedTest button');

/**
 * @type {SingleUpload}
 * @description upload实例对象
 */
let upload = null;


// 初始时按钮禁用
uploadBtn.disabled = true;

/**
 * axios的onUploadProgress事件监听
 * @param {number} index 分片的序号
 * @returns {function}
 */
function handleUploadProgress(index) {
    return function handleAxiosProgress(progress) {
        upload.uploaded[index] = progress.loaded;
        const uploaded = upload.uploaded.reduce((res, val) => res + val, 0);
        const currentProgress = (uploaded / upload.file.size) * 100;
        progressBar.value = currentProgress;
    };
}

/**
 * 处理计算hash进度的回调
 * @param {number} percentage
 */
function handleHashProgress(percentage) {
    hashProgress.value = percentage;
}

/**
 * input监听文件上传
 * @param {Event} e
 * @returns
 */
function handleFileChange(e) {
    const [file] = e.target.files;
    if (!file) {
        return;
    }
    upload = new SingleUpload(file, {
        checkUrl: '/check',
        uploadUrl: '/upload',
        mergeUrl: '/merge',
        size: SIZE,
        concurrency: CONCURRENCY,
        retries: RETRIES,
        handleHashProgress,
        handleUploadProgress
    });
    uploadBtn.disabled = false;
}

/** 重置ui */
function reset() {
    progressBar.value = 0;
    hashProgress.value = 0;
    uploadBtn.disabled = true;
    upload.uploaded = [];
}

/**
 *
 * @param {{data, status:number}} checkRes check请求返回的axios响应对象
 * @returns {boolean} 是否该终止文件上传过程
 */
function afterCheck(checkRes) {
    if (checkRes.data.exits) {
        alert('文件已存在！');
        reset();
        fileURL.href = checkRes.fileURL;
        fileURL.textContent = upload.file.name;
        return true;
    }
    return false;
}

/**
 *
 * @param {number} during 上传文件所耗费时间
 * @param {{data, status:number}} mergeRes merge请求返回的axios响应对象
 */
function afterUpload(during, mergeRes) {
    cost.textContent = `耗时：${during} ms`;
    fileURL.href = mergeRes.data.fileURL;
    fileURL.textContent = upload.file.name;
    alert('上传成功！');
    reset();
}

async function testUploadSpeed(testURL = '/speed-test', fileSizeInBytes = 1024 * 1024 * 100) {
    console.log(fileSizeInBytes)
    const data = new Blob([new Uint8Array(fileSizeInBytes).fill(0).map(() => Math.random() * 256)], { type: 'application/octet-stream' });
    console.log(data);
    const startTime = Date.now();

    const res = await fetch(testURL, {
        method: 'POST',
        body: data
    });

    const text = await res.text();
    console.log(text);

    const endTime = Date.now();
    const duration = (endTime - startTime) / 1000; // Duration in seconds


    const speedMbps = (fileSizeInBytes / 1024 / 1024 / duration).toFixed(2);


    console.log(`Upload: ${speedMbps} Mbps`);
    return speedMbps;
}

speedTestButton.addEventListener('click', () => testUploadSpeed());
// testUploadSpeed();


/**
 * 处理上传事件
 */
function handleUpload() {
    upload.start(afterCheck, afterUpload);
}

// 事件监听
file.addEventListener('change', handleFileChange);
uploadBtn.addEventListener('click', handleUpload);
